<template>
  <Category :isShow="contentShow" />
  <el-card style="margin: 30px 0px">
    <!-- 属性列表展示 -->
    <div v-show="contentShow === 0">
      <el-button type="primary" :disabled="!thirdCateId" icon="Plus" @click="addAttr"
        >添加属性</el-button
      >
      <el-table :data="hasAttrArr" style="width: 100%; margin: 10px 0px" border>
        <el-table-column type="index" label="序号" align="center" width="80px">
        </el-table-column>
        <el-table-column prop="attrName" label="属性名称" align="center" width="150px">
        </el-table-column>
        <el-table-column label="属性值名称" align="center">
          <template #="{ row, $index }">
            <el-tag
              style="margin: 5px"
              type="success"
              v-for="item in row.attrValueList"
              :key="$index"
              >{{ item.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="150px">
          <!-- row：操作对应行的数据对象 -->
          <template #="{ row }">
            <el-button
              type="warning"
              size="small"
              icon="Edit"
              @click="updateAttr(row)"
            ></el-button>
            <el-popconfirm
              :title="`确定删除属性【${row.attrName}】?`"
              @confirm="deleteAttr(row)"
            >
              <template #reference>
                <el-button type="danger" size="small" icon="Delete"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 属性添加和修改页面展示 -->
    <div v-show="contentShow === 1">
      <el-form label-width="68px" :inline="true">
        <el-form-item label="属性名称">
          <el-input placeholder="请输入内容" v-model="attrParams.attrName"></el-input>
        </el-form-item>
      </el-form>
      <el-button
        type="primary"
        icon="Plus"
        :disabled="!attrParams.attrName"
        @click="addAttrValue"
        >添加属性值</el-button
      >
      <el-button type="default" @click="cancel">取消</el-button>
      <el-table
        :data="attrParams.attrValueList"
        style="width: 100%; margin: 20px 0px"
        border
      >
        <el-table-column type="index" label="序号" align="center" width="100px">
        </el-table-column>
        <el-table-column label="属性值" align="center">
          <template #="{ row, $index }">
            <el-input
              v-input-focus
              v-if="row.flag"
              v-model="row.valueName"
              size="default"
              placeholder="请输入属性值"
              @blur="toLook(row, $index)"
            />
            <div v-else @click="toEdit(row)">{{ row.valueName }}</div>
          </template>
        </el-table-column>
        <el-table-column prop="prop" label="操作" align="center">
          <template #="{ $index }">
            <el-button
              type="danger"
              icon="Delete"
              @click="removeAttrValue($index)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button
        type="primary"
        :disabled="!attrParams.attrValueList.length"
        @click="saveAttr"
        >保存</el-button
      >
      <el-button type="default" @click="cancel">取消</el-button>
    </div>
  </el-card>
</template>

<script setup lang="ts">
import { useCategoryStore } from "@/store/modules/category";
import { storeToRefs } from "pinia";
import { ref, watch, onBeforeUnmount } from "vue";
import { reqHasAttr, reqAddOrEditAttr, reqDeleteAttr } from "@/api/product/attr";
import type { AttrObj, AttrResData, AttrValueObj } from "@/api/product/attr/types";
import { ElMessage } from "element-plus";
// 分类仓库对象
const categoryStore = useCategoryStore();
// 解构出收集的三级分类Id 来判断 添加按钮是否禁用
const { primCateId, secCateId, thirdCateId } = storeToRefs(categoryStore);
// 分类已有的属性
const hasAttrArr = ref<AttrObj[]>([]);
// 控制el-card展示内容的切换
// 0表示展示属性列表、1表示展示添加和修改页面
const contentShow = ref<number>(0);
// 收集新增的属性数据
const attrParams = ref<AttrObj>({
  attrName: "", // 属性名
  attrValueList: [],
  categoryId: "", // 三级分类Id
  categoryLevel: 3, // 三级分类
});
// 输入框ref
// const inputRef = ref();

// 监听三级分类Id变化
// 使用el-select的change事件可以获取数据，但不建议使用子组件事件获取父组件数据
watch(thirdCateId, (newValue) => {
  // 三级分类Id变化时，清空属性数组，因为切换三级分类失败时还会展示之前的数据
  hasAttrArr.value = [];
  // 保证三级分类Id存在时才去发请求获取属性
  if (!newValue) return;
  getHasAttr();
});
// 获取分类已有的属性
const getHasAttr = async () => {
  let result: AttrResData = await reqHasAttr(
    primCateId.value,
    secCateId.value,
    thirdCateId.value
  );
  if (result?.code === 200) {
    hasAttrArr.value = result.data;
  }
};
// 添加属性按钮回调
const addAttr = () => {
  // 点击添加按钮时，先清空attrParams数据，再收集数据
  attrParams.value = {
    attrName: "", // 属性名
    attrValueList: [],
    categoryId: thirdCateId.value, // 三级分类Id
    categoryLevel: 3, // 三级分类
  };
  contentShow.value = 1;
};
// 修改属性按钮回调
const updateAttr = (row: AttrObj) => {
  contentShow.value = 1;
  // 将已有的属性对象赋值给attrParams
  // 不能直接赋值，因为是一个对象，直接赋值是浅拷贝，需要深拷贝
  attrParams.value = JSON.parse(JSON.stringify(row));
};
// 删除属性按钮回调
const deleteAttr = async (row: AttrObj) => {
  let result: any = await reqDeleteAttr(row.id as number);
  if (result?.code === 200) {
    ElMessage({
      type: "success",
      message: "删除成功",
    });
    getHasAttr();
  } else {
    ElMessage({
      type: "error",
      message: "删除失败",
    });
  }
};
// 添加属性值按钮回调
const addAttrValue = () => {
  // 点击添加属性值按钮，就向属性值数组中加入一条记录
  // flag：用来控制表格内容的切换
  attrParams.value.attrValueList.push({
    valueName: "",
    flag: true,
  });
  // 点击添加属性值按钮时，让输入框自动获取焦点，通过自定义指令已实现(也可通过下面语句)
  /* nextTick(() => {
    inputRef.value.focus();
  }); */
};
// 取消按钮回调
const cancel = () => {
  contentShow.value = 0;
};
// 失去焦点方法
const toLook = (row: AttrValueObj, $index: number) => {
  // 非法情况1：属性值为空
  if (!row.valueName.trim()) {
    // 给出错误提示
    ElMessage({
      type: "error",
      message: "属性值不能为空",
    });
    // 并清除空数据
    attrParams.value.attrValueList.splice($index, 1);
    return;
  }
  // 非法情况2：填入重复数据
  const repeat = attrParams.value.attrValueList.some((item, index) => {
    // 需要先将当前数据从数组中排除，只去比较其他值
    if (index !== $index) {
      return item.valueName === row.valueName;
    }
  });
  if (repeat) {
    ElMessage({
      type: "error",
      message: "属性值重复，请重新输入",
    });
    return;
  }
  row.flag = false;
};
// 属性值div点击事件回调
const toEdit = (row: AttrValueObj) => {
  row.flag = true;
  // 点击div时，让输入框自动获取焦点，通过自定义指令已实现（也可通过下面语句）
  /* nextTick(() => {
    inputRef.value.focus();
  }); */
};
// 删除属性值回调
const removeAttrValue = (index: number) => {
  attrParams.value.attrValueList.splice(index, 1);
};
// 保存按钮的回调
const saveAttr = async () => {
  // 发送请求保存属性
  let result: any = await reqAddOrEditAttr(attrParams.value);
  if (result?.code === 200) {
    contentShow.value = 0;
    ElMessage({
      type: "success",
      message: attrParams.value.id ? "修改成功" : "添加成功",
    });
    // 重新获取数据
    getHasAttr();
  } else {
    ElMessage({
      type: "error",
      message: attrParams.value.id ? "修改失败" : "添加失败",
    });
  }
};
// 离开组件后，清空所有的分类数据
onBeforeUnmount(() => {
  categoryStore.$reset();
});
</script>

<style scoped></style>
